#ifndef HUGINT_H
#define HUGINT_H

#include <string>
#include <deque>
#include <algorithm>
#include <iostream>
#include <cstring>
#include <exception>
using namespace std;

class HugeInteger {
public:
    HugeInteger (long long = 0);
    HugeInteger (string);
    HugeInteger (const char *);

    const HugeInteger operator+ (const HugeInteger &) const;
    const HugeInteger operator- (const HugeInteger &) const;
    const HugeInteger operator* (const HugeInteger &) const;
    const HugeInteger operator/ (const HugeInteger &) const;

    bool operator< (const HugeInteger & a) const
    {
        return str () < a.str ();
    }

    bool operator== (const HugeInteger & a) const
    {
        return str () == a.str ();
    }

    bool operator> (const HugeInteger & a) const
    {
        return a < *this;
    }

    bool operator<= (const HugeInteger & a) const
    {
        return *this < a || a == *this;
    }

    bool operator>= (const HugeInteger & a) const
    {
        return a < *this || a == *this;
    }

    size_t length () const; // return the length of the number

    string str () const; // cast hunsigned to string
    long long number () const; // cast hunsigned to long
    void print (ostream & = cout) const;

private:
    int & at (size_t); // return the nth element
    int at (size_t) const;

    void reserve (size_t);
    void push_back (int);
    void push_front (int);
    size_t size () const; // return number of elements

    void from_string (const char *);

    typedef deque<int> number_t;
    number_t numbers;

    enum {
        base = 10
    };
};

ostream & operator<< (ostream &, const HugeInteger &);
istream & operator>> (istream &, HugeInteger &);

typedef HugeInteger hint;

#endif
